bitkeeper revision 1.1272.1.1 (425b95a8cRhux_vtKXZDHhnHcViWRg)
authormafetter@fleming.research <mafetter@fleming.research>
Tue, 12 Apr 2005 09:32:24 +0000 (09:32 +0000)
committermafetter@fleming.research <mafetter@fleming.research>
Tue, 12 Apr 2005 09:32:24 +0000 (09:32 +0000)
Patch to run a domU in shadow test mode.

15 files changed:
linux-2.6.11-xen-sparse/arch/xen/Kconfig
linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32
linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32
linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c
linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h
linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
tools/libxc/xc_linux_build.c
xen/arch/x86/domain.c
xen/arch/x86/mm.c
xen/arch/x86/shadow.c
xen/common/dom_mem_ops.c
xen/include/asm-x86/shadow.h
xen/include/xen/perfc_defn.h

index 8205344169d143c3a223b5614b9865ad3e0cd0f6..1e766a2e0599524939dba083da352d13ce4e60d0 100644 (file)
@@ -123,6 +123,13 @@ config XEN_BLKDEV_TAP
          to a character device, allowing device prototyping in application
          space.  Odds are that you want to say N here.
 
+config XEN_SHADOW_MODE
+       bool "Fake shadow mode"
+       default n
+    help
+      fakes out a shadow mode kernel
+
+
 config XEN_SCRUB_PAGES
        bool "Scrub memory before freeing it to Xen"
        default y
index a781740c94722e81f208e3a92b97cd3376c5e153..096f4fd1c2425ddd1e975608d303133e55ae87fb 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_PHYSDEV_ACCESS=y
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
+# CONFIG_XEN_BLKDEV_GRANT is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
index b1fc951a81f426b1e45be50ede3cfcc93c77986e..4ec4c44bfc02f7f13aa13c7094523f1f81fd45ff 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.11-xenU
-# Fri Mar 11 01:20:28 2005
+# Tue Apr  5 16:44:33 2005
 #
 CONFIG_XEN=y
 CONFIG_ARCH_XEN=y
@@ -12,10 +12,12 @@ CONFIG_NO_IDLE_HZ=y
 #
 # CONFIG_XEN_PRIVILEGED_GUEST is not set
 # CONFIG_XEN_PHYSDEV_ACCESS is not set
+# CONFIG_XEN_BLKDEV_GRANT is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_SHADOW_MODE=y
 CONFIG_XEN_SCRUB_PAGES=y
 CONFIG_X86=y
 # CONFIG_X86_64 is not set
index c7b79528ff6d88e8a9ed31f261b54ede9bb4b842..0d212b295ac64497f4a4fe3b93778aab03cc3328 100644 (file)
@@ -48,6 +48,7 @@
 #define pmd_val_ma(v) (v).pud.pgd.pgd;
 #endif
 
+#ifndef CONFIG_XEN_SHADOW_MODE
 void xen_l1_entry_update(pte_t *ptr, unsigned long val)
 {
     mmu_update_t u;
@@ -63,6 +64,7 @@ void xen_l2_entry_update(pmd_t *ptr, pmd_t val)
     u.val = pmd_val_ma(val);
     BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
 }
+#endif
 
 void xen_machphys_update(unsigned long mfn, unsigned long pfn)
 {
@@ -131,6 +133,7 @@ void xen_invlpg_mask(cpumask_t mask, unsigned long ptr)
 
 #endif /* CONFIG_SMP */
 
+#ifndef CONFIG_XEN_SHADOW_MODE
 void xen_pgd_pin(unsigned long ptr)
 {
     struct mmuext_op op;
@@ -162,6 +165,7 @@ void xen_pte_unpin(unsigned long ptr)
     op.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
     BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
 }
+#endif
 
 void xen_set_ldt(unsigned long ptr, unsigned long len)
 {
index 15ad452eb42395be6a62130d94b218c646bd92d5..fcc7b4e144a14fcac66c0313afc27a83c9fe82ac 100644 (file)
@@ -366,6 +366,7 @@ void pgd_free(pgd_t *pgd)
        kmem_cache_free(pgd_cache, pgd);
 }
 
+#ifndef CONFIG_XEN_SHADOW_MODE
 void make_lowmem_page_readonly(void *va)
 {
        pgd_t *pgd = pgd_offset_k((unsigned long)va);
@@ -437,3 +438,4 @@ void make_pages_writable(void *va, unsigned int nr)
                va = (void *)((unsigned long)va + PAGE_SIZE);
        }
 }
+#endif /* CONFIG_XEN_SHADOW_MODE */
index 33ded533b246d16321d87ae7bd8c947dec4adcb4..b25099b6fcdf407bc3f7e96a0ebedb2565db5f99 100644 (file)
  */
 #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
 #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
+
+#ifndef CONFIG_XEN_SHADOW_MODE
 #define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
+#else
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+#endif
 
 #define ptep_get_and_clear(xp) __pte_ma(xchg(&(xp)->pte_low, 0))
 #define pte_same(a, b)         ((a).pte_low == (b).pte_low)
index 5afb8ced1f805087f7044dab68e0e9d8f647bd93..c0782ed7a0f8ac0549d5f7c11738ed69b7cb32ba 100644 (file)
@@ -432,12 +432,21 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
+#ifndef CONFIG_XEN_SHADOW_MODE
 void make_lowmem_page_readonly(void *va);
 void make_lowmem_page_writable(void *va);
 void make_page_readonly(void *va);
 void make_page_writable(void *va);
 void make_pages_readonly(void *va, unsigned int nr);
 void make_pages_writable(void *va, unsigned int nr);
+#else
+#define make_lowmem_page_readonly(_va) ((void)0)
+#define make_lowmem_page_writable(_va) ((void)0)
+#define make_page_readonly(_va)        ((void)0)
+#define make_page_writable(_va)        ((void)0)
+#define make_pages_readonly(_va, _nr)  ((void)0)
+#define make_pages_writable(_va, _nr)  ((void)0)
+#endif
 
 #define arbitrary_virt_to_machine(__va)                                        \
 ({                                                                     \
index 116e0df853972d03f0aad56242a8141e79858a81..f64d1caffb9ad563eda610745e5e885b6cb8ba76 100644 (file)
@@ -71,15 +71,26 @@ void lgdt_finish(void);
  * be MACHINE addresses.
  */
 
-void xen_l1_entry_update(pte_t *ptr, unsigned long val);
-void xen_l2_entry_update(pmd_t *ptr, pmd_t val);
 void xen_pt_switch(unsigned long ptr);
 void xen_tlb_flush(void);
 void xen_invlpg(unsigned long ptr);
+
+#ifndef CONFIG_XEN_SHADOW_MODE
+void xen_l1_entry_update(pte_t *ptr, unsigned long val);
+void xen_l2_entry_update(pmd_t *ptr, pmd_t val);
 void xen_pgd_pin(unsigned long ptr);
 void xen_pgd_unpin(unsigned long ptr);
 void xen_pte_pin(unsigned long ptr);
 void xen_pte_unpin(unsigned long ptr);
+#else
+#define xen_l1_entry_update(_p, _v) set_pte((_p), (pte_t){(_v)})
+#define xen_l2_entry_update(_p, _v) set_pgd((_p), (pgd_t){(_v)})
+#define xen_pgd_pin(_p)   ((void)0)
+#define xen_pgd_unpin(_p) ((void)0)
+#define xen_pte_pin(_p)   ((void)0)
+#define xen_pte_unpin(_p) ((void)0)
+#endif
+
 void xen_set_ldt(unsigned long ptr, unsigned long bytes);
 void xen_machphys_update(unsigned long mfn, unsigned long pfn);
 
index d4b28de06eb7d029668943a5faa183e3f3fa4aea..108d5911076472e47e29a3e1f5e27e3d53c95d9a 100644 (file)
@@ -210,9 +210,11 @@ static int setup_guest(int xc_handle,
         }
 
         *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
+#if !(1 || defined(GROSS_HACK_TO_TEST_SHADOW_MODE_CLIENTS))
         if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && 
              (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) )
             *vl1e &= ~_PAGE_RW;
+#endif
         vl1e++;
     }
     munmap(vl1tab, PAGE_SIZE);
@@ -243,12 +245,25 @@ static int setup_guest(int xc_handle,
     }
     munmap(physmap, PAGE_SIZE);
     
+#if 1 || defined(GROSS_HACK_TO_TEST_SHADOW_MODE_CLIENTS)
+    {
+        int ret;
+        ret = xc_shadow_control(xc_handle, dom,
+                                DOM0_SHADOW_CONTROL_OP_ENABLE_TEST,
+                                NULL, 0, NULL);
+        if ( !ret )
+            ERROR("enabling shadow test mode failed\n");
+    }
+#endif
+
     /*
      * Pin down l2tab addr as page dir page - causes hypervisor to provide
      * correct protection for the page
      */ 
+#if !(1 || defined(GROSS_HACK_TO_TEST_SHADOW_MODE_CLIENTS))
     if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, l2tab>>PAGE_SHIFT, dom) )
         goto error_out;
+#endif
 
     start_info = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
index 322181ffdb1cb7b9ae5cd0f1792301d3b6d02526..a00fdb6fd1465afc0d247ddf2bb37d3aa94d0f86 100644 (file)
@@ -440,9 +440,17 @@ int arch_set_info_guest(
     phys_basetab = c->pt_base;
     ed->arch.guest_table = mk_pagetable(phys_basetab);
 
-    if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
-                            PGT_base_page_table) )
-        return -EINVAL;
+    if ( shadow_mode_enabled(d) )
+    {
+        if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
+            return -EINVAL;
+    }
+    else
+    {
+        if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
+                                PGT_base_page_table) )
+            return -EINVAL;
+    }
 
     /* Failure to set GDT is harmless. */
     SET_GDT_ENTRIES(ed, DEFAULT_GDT_ENTRIES);
index 14c2de1bb6822fc8708e380af9d612bafb3d8e2b..05a5a3649cf7a1dc520fac18e018445e4c0daa35 100644 (file)
@@ -1897,8 +1897,11 @@ int do_mmu_update(
                         gpfn = __mfn_to_gpfn(d, mfn);
                         ASSERT(VALID_M2P(gpfn));
 
-                        if ( page_is_page_table(page) )
+                        if ( page_is_page_table(page) &&
+                             !page_out_of_sync(page) )
+                        {
                             shadow_mark_mfn_out_of_sync(ed, gpfn, mfn);
+                        }
                     }
 
                     *(unsigned long *)va = req.val;
@@ -2152,7 +2155,7 @@ int do_update_va_mapping(unsigned long va,
             local_flush_tlb();
             break;
         case UVMF_ALL:
-            BUG_ON(shadow_mode_enabled(d));
+            BUG_ON(shadow_mode_enabled(d) && (d->cpuset != (1<<cpu)));
             flush_tlb_mask(d->cpuset);
             break;
         default:
@@ -2173,7 +2176,7 @@ int do_update_va_mapping(unsigned long va,
             local_flush_tlb_one(va);
             break;
         case UVMF_ALL:
-            BUG_ON(shadow_mode_enabled(d));
+            BUG_ON(shadow_mode_enabled(d) && (d->cpuset != (1<<cpu)));
             flush_tlb_one_mask(d->cpuset, va);
             break;
         default:
@@ -2391,7 +2394,7 @@ long do_update_descriptor(unsigned long pa, u64 desc)
         if ( shadow_mode_log_dirty(dom) )
             __mark_dirty(dom, mfn);
 
-        if ( page_is_page_table(page) )
+        if ( page_is_page_table(page) && !page_out_of_sync(page) )
             shadow_mark_mfn_out_of_sync(current, gpfn, mfn);
     }
 
index 1d317f343386e3d0056ac9f0c456ed9477cabd4d..065f098b9191d4c5b62f2bf9dbe0881284222f7a 100644 (file)
@@ -515,10 +515,10 @@ static void free_shadow_pages(struct domain *d)
      * e.g., You are expected to have paused the domain and synchronized CR3.
      */
 
-    shadow_audit(d, 1);
-
     if( !d->arch.shadow_ht ) return;
 
+    shadow_audit(d, 1);
+
     // first, remove any outstanding refs from out_of_sync entries...
     //
     free_out_of_sync_state(d);
@@ -1663,7 +1663,7 @@ shadow_mark_mfn_out_of_sync(struct exec_domain *ed, unsigned long gpfn,
     ASSERT(pfn_is_ram(mfn));
     ASSERT((page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page);
 
-    FSH_LOG("mark_mfn_out_of_sync(gpfn=%p, mfn=%p) c=%p t=%p",
+    FSH_LOG("%s(gpfn=%p, mfn=%p) c=%p t=%p", __func__,
             gpfn, mfn, page->count_info, page->u.inuse.type_info);
 
     // XXX this will require some more thought...  Cross-domain sharing and
@@ -2031,6 +2031,7 @@ u32 shadow_remove_all_access(struct domain *d, unsigned long forbidden_gmfn)
     u32 count = 0;
 
     ASSERT(spin_is_locked(&d->arch.shadow_lock));
+    perfc_incrc(remove_all_access);
 
     for (i = 0; i < shadow_ht_buckets; i++)
     {
@@ -2622,14 +2623,6 @@ static int check_l1_table(
     unsigned long *gpl1e, *spl1e;
     int errors = 0, oos_ptes = 0;
 
-    // First check to see if this guest page is currently the active
-    // PTWR page.  If so, then we compare the (old) cached copy of the
-    // guest page to the shadow, and not the currently writable (and
-    // thus potentially out-of-sync) guest page.
-    //
-    if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) )
-        BUG();
-
     if ( page_out_of_sync(pfn_to_page(gmfn)) )
     {
         gmfn = __shadow_status(d, gpfn, PGT_snapshot);
@@ -2743,7 +2736,7 @@ int _check_pagetable(struct exec_domain *ed, char *s)
     unsigned long ptbase_mfn = 0;
     int errors = 0, limit, oos_pdes = 0;
 
-    _audit_domain(d, AUDIT_QUIET);
+    //_audit_domain(d, AUDIT_QUIET);
     shadow_lock(d);
 
     sh_check_name = s;
index d1f4d393022b543472108601b6d29c2240522d9d..06e1aca0fae526a95d9afcc3ed1028e34c11adaf 100644 (file)
@@ -121,15 +121,6 @@ free_dom_mem(struct domain *d,
                 if ( page_out_of_sync(page) )
                     __shadow_sync_mfn(d, mpfn + j);
                 shadow_remove_all_access(d, mpfn + j);
-
-                if (page->count_info != 1)
-                {
-                    printk("free_dom_mem in shadow mode didn't release page "
-                           "mfn=%p c=%p\n", mpfn+j, page->count_info);
-                    shadow_unlock(d);
-                    audit_domain(d);
-                    BUG();
-                }
                 shadow_unlock(d);
             }
 
index 4aa84b1d17b5e285a017d23e6aab58946e24b6d6..11a6f9b972f052d030072fdf19d5389d8c842e2d 100644 (file)
@@ -222,11 +222,11 @@ struct out_of_sync_entry {
 #define SHADOW_SNAPSHOT_ELSEWHERE (-1L)
 
 /************************************************************************/
-#define SHADOW_DEBUG 1
-#define SHADOW_VERBOSE_DEBUG 1
-#define SHADOW_VVERBOSE_DEBUG 1
-#define SHADOW_HASH_DEBUG 1
-#define FULLSHADOW_DEBUG 1
+#define SHADOW_DEBUG 0
+#define SHADOW_VERBOSE_DEBUG 0
+#define SHADOW_VVERBOSE_DEBUG 0
+#define SHADOW_HASH_DEBUG 0
+#define FULLSHADOW_DEBUG 0
 
 #if SHADOW_DEBUG
 extern int shadow_status_noswap;
@@ -1444,14 +1444,18 @@ extern void __update_pagetables(struct exec_domain *ed);
 static inline void update_pagetables(struct exec_domain *ed)
 {
     struct domain *d = ed->domain;
+    int paging_enabled;
 
 #ifdef CONFIG_VMX
-    int paging_enabled =
-        !VMX_DOMAIN(ed) ||
-        test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
-#else
-    const int paging_enabled = 1;
+    if ( VMX_DOMAIN(ed) )
+        paging_enabled =
+            test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
+    else
 #endif
+        // HACK ALERT: there's currently no easy way to figure out if a domU
+        // has set its arch.guest_table to zero, vs not yet initialized it.
+        //
+        paging_enabled = !!pagetable_val(ed->arch.guest_table);
 
     /*
      * We don't call __update_pagetables() when vmx guest paging is
index 0d5b146432650776de2d7eefcd6d6c152065fee0..501851ec55d147dbecb4a05b189029ef97f4570c 100644 (file)
@@ -99,6 +99,7 @@ PERFCOUNTER_CPU(validate_hl2e_calls,               "calls to validate_hl2e_chang
 PERFCOUNTER_CPU(validate_hl2e_changes,             "validate_hl2e makes changes")
 PERFCOUNTER_CPU(exception_fixed,                   "pre-exception fixed")
 PERFCOUNTER_CPU(gpfn_to_mfn_foreign,               "calls to gpfn_to_mfn_foreign")
+PERFCOUNTER_CPU(remove_all_access,                 "calls to remove_all_access")
 PERFCOUNTER_CPU(remove_write_access,               "calls to remove_write_access")
 PERFCOUNTER_CPU(remove_write_access_easy,          "easy outs of remove_write_access")
 PERFCOUNTER_CPU(remove_write_no_work,              "no work in remove_write_access")